package parser;


import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.*;
import java.text.ParseException;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class App {
    public static void main(String[] args) {
        System.out.println("程序开始");

        SAXReader reader = new SAXReader();
        Document document;

        try {

            String bBox = "120,40,130,45";//经纬度范围
            String time = "2018-09-04T03:18:01Z,2018-09-05T03:18:01Z";//时间段
            System.out.println("开始请求");


            URL url = new URL("https://api.openstreetmap.org/api/0.6/changesets?time=" + time + "&bbox=" + bBox);
            //忽略https验证
            if ("https".equalsIgnoreCase(url.getProtocol())) {
                SslUtils.ignoreSsl();
            }
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 打开连接
            connection.connect();// 连接会话
            document = reader.read(connection.getInputStream());
            Element root = document.getRootElement();
            System.out.println("程序开始");

            //遍历孩子元素,解析数据
            for (Iterator<Element> it = root.elementIterator(); it.hasNext(); ) {
                Element element = it.next();
                int id = Integer.parseInt(element.attributeValue("id"));
                System.out.println("获取changeSet" + id);
                getChangeSetById(id);
            }
            connection.disconnect();
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void getChangeSetById(int id) {
        SAXReader reader = new SAXReader();
        Document document;
        try {
            URL url = new URL("https://www.openstreetmap.org/api/0.6/changeset/" + id + "/download");
            System.out.println("https://www.openstreetmap.org/api/0.6/changeset/" + id + "/download");
            //忽略https验证
            if ("https".equalsIgnoreCase(url.getProtocol())) {
                SslUtils.ignoreSsl();
            }
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 打开连接
            connection.connect();// 连接会话
            document = reader.read(connection.getInputStream());
            List<Point> points = new ArrayList<>();
//            Element root = document.getRootElement();
            List nodes = document.selectNodes("//node");
            for (Iterator i = nodes.iterator(); i.hasNext(); ) {
                Element node = (Element) i.next();
                Point point = new Point();
                point.setId(Long.parseLong(node.attributeValue("id")));
                point.setLat(Double.parseDouble(node.attributeValue("lat")));
                point.setLon(Double.parseDouble(node.attributeValue("lon")));
                System.out.println(point.toString());
                points.add(point);
            }
            List<Way> modeify=getWay(points,document,"modify","修改");
            List<Way> delete=getWay(points,document,"delete","删除");
            List<Way> add=getWay(points,document,"add","增加");

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static Point getPointById(List<Point> points,Long id){
        Point point=null;
        for (int i = 0; i <points.size() ; i++) {
            if(id.equals(points.get(i).getId())){
                point=points.get(i);
                break;
            }
        }
        return point;
    }

    public static List<Way> getWay(List<Point> points,Document document,String type1,String type2){
        List<Way> ways = new ArrayList<>();
        List ways_modify = document.selectNodes("//"+type1+"/way");
        for (Iterator i = ways_modify.iterator(); i.hasNext(); ) {
            Way way_=new Way();
            Element way = (Element) i.next();
            way_.setEditType(type2);
            way_.setId(Long.parseLong(way.attributeValue("id")));
            way_.setUser(way.attributeValue("user"));
            way_.setVersion(Integer.valueOf(way.attributeValue("version")));
            way_.setTimestamp(Timestamp.valueOf(way.attributeValue("timestamp")));
            for (Iterator<Element> it = way.elementIterator("nd"); it.hasNext(); ) {
                Element nd = it.next();
                Point point=getPointById(points, Long.valueOf(nd.attributeValue("ref")));
                way_.addPoint(point);
            }
            ways.add(way_);
        }
        return ways;
    }

    /**
     * 将查到的信息存入数据库
     *
     * @param list
     */
    private static void putIntoDataBase(List<Record> list) {
        Connection c = null;
        Statement stmt = null;

        try {
            //配置数据库连接
            Class.forName("org.postgresql.Driver");

            c = DriverManager
                    .getConnection("jdbc:postgresql://localhost:5432/postgres",
                            "postgres", "postgres");
            stmt = c.createStatement();
            //检查表是否存在,不存在则创建表
            String checkTable = "create table if not exists street(" +
                    "    id integer," +
                    "    min_lat double precision," +
                    "    min_lon double precision," +
                    "    max_lat double precision," +
                    "    max_lon double precision," +
                    "    created_at text," +
                    "    closed_at text," +
                    "    open boolean," +
                    "    comments_count integer," +
                    "    changes_count integer," +
                    "    uid integer," +
                    "    \"user\" text," +
                    "    geom geometry" +
                    ");";
            stmt.execute(checkTable);
            //导入数据
            for (Record record : list) {
                String sql = "INSERT INTO street (id, min_lat, min_lon, max_lat, max_lon, created_at, closed_at, open, comments_count, changes_count, uid, \"user\", geom) "
                        + "VALUES (" + record.id +
                        ", " + record.min_lat +
                        "," + record.min_lon +
                        "," + record.max_lat +
                        "," + record.max_lon +
                        ",'" + record.created_at +
                        "','" + record.closed_at +
                        "'," + record.open +
                        "," + record.comments_count +
                        "," + record.changes_count +
                        "," + record.uid +
                        ",'" + record.user +
                        "'," + record.getGeom() +
                        " );";
                System.out.println(sql);
                stmt.executeUpdate(sql);
            }
            stmt.close();
            c.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
